package com.xm.httpapi.BaseApi;

import com.xm.httpapi.BaseApi.Interceptor.LoggingInterceptor;
import com.xm.httpapi.BaseUtils.LogUtils;
import com.xm.httpapi.BaseUtils.SSLSocketFactoryCompat;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
/**
 * Author:guohaijin
 * Date:
 * Description:
 */
public class BaseApi {
    /**
     * 请求成功的code的值默认是0
     */
    public static int ReponseSucessCode = 0;

    /**
     * token过期的code值默认是10
     */
    public static int ReponseTokenInvalidCode = 10;
    /**
     * 请求默认超时时间
     */
    private int timeOut = 10;
    /**
     * 请求url
     */
    private String url;
    /**
     * 是否打印http请求日志
     */
    private boolean isPrintHttpInfo = true;
    /**
     * 是否添加http日志拦截器
     */
    private boolean isHttpLoggingInterceptor = true;
    /**
     * 是否添加https证书
     */
    private int intSSLSocketFactory = -1;//-1不添加 0 通用  1自定义

    private Map<String, String> headMap;

    private SSLSocketFactory sslSocketFactory;

    public BaseApi(String url) {
        this.url = url;
    }

    public BaseApi(String url, int timeOut) {
        this.url = url;
        this.timeOut = timeOut;
    }

    public BaseApi(String url, int timeOut, int ReponseSucessCode, int ReponseTokenInvalidCode) {
        this.url = url;
        this.timeOut = timeOut;
        this.ReponseSucessCode = ReponseSucessCode;
        this.ReponseTokenInvalidCode = ReponseTokenInvalidCode;
    }

    /**
     * @是否添加http日志拦截器
     */
    public void setHttpLoggingInterceptor(boolean httpLoggingInterceptor) {
        this.isHttpLoggingInterceptor = httpLoggingInterceptor;
    }

    /**
     * @是否打印http请求日志
     */
    public void setPrintHttpInfo(boolean printHttpInfo) {
        this.isPrintHttpInfo = printHttpInfo;
    }

    /**
     * @设置头部map里面的值
     */
    public void setHeadMap(Map headMap) {
        this.headMap = headMap;
    }

    /**
     * @清除头部map里面的值
     */
    public void clearHeadMap() {
        if (headMap != null) headMap.clear();
    }

    /**
     * @param intSSLSocketFactory -1:不添加  0:通用 1:自定义(需要传 SSLSocketFactory )
     * @是否添加https证书
     */
    public void setSSLSocketFactory(int intSSLSocketFactory) {
        setSSLSocketFactory(intSSLSocketFactory, null);
    }

    /**
     * @param intSSLSocketFactory -1:不添加  0:通用 1:自定义(需要传 SSLSocketFactory )
     * @是否添加https证书
     */
    public void setSSLSocketFactory(int intSSLSocketFactory, SSLSocketFactory sslSocketFactory) {
        this.intSSLSocketFactory = intSSLSocketFactory;
        if (intSSLSocketFactory == 1) {
            this.sslSocketFactory = sslSocketFactory;
        }
    }

    /**
     * @清除自定义证书
     */
    public void clearSSLSocketFactory() {
        if (sslSocketFactory != null) sslSocketFactory = null;
    }


    private OkHttpClient.Builder okHttpClient() {
        //手动创建一个OkHttpClient并设置超时时间
        OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
        httpClientBuilder.connectTimeout(timeOut, TimeUnit.SECONDS);
        httpClientBuilder.writeTimeout(timeOut, TimeUnit.SECONDS);
        httpClientBuilder.readTimeout(timeOut, TimeUnit.SECONDS);
        //是否添加打印日志的拦截器
        if (isHttpLoggingInterceptor) httpClientBuilder.addInterceptor(new LoggingInterceptor());
        //是否添加请求头的拦截器
        if (headMap != null && !headMap.isEmpty()) {
            httpClientBuilder.addInterceptor(interceptor(headMap));
        }
        //是否添加https的证书
        if (intSSLSocketFactory == 1 && sslSocketFactory != null) {
            httpClientBuilder.sslSocketFactory(sslSocketFactory, x509TrustManager());
        } else if (intSSLSocketFactory != -1) {
            httpClientBuilder.sslSocketFactory(new SSLSocketFactoryCompat(x509TrustManager()), x509TrustManager());
        }
        return httpClientBuilder;
    }


    public Retrofit getRetrofit() {
        return new Retrofit.Builder()
                .client(okHttpClient().build())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(url)
                .addConverterFactory(CustomGsonConverterFactory.create())
                .build();
    }

    private HttpLoggingInterceptor httpLoggingInterceptor() {
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(message -> {
            if (isPrintHttpInfo) LogUtils.e("httpinfo= " + message);
        });
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        return loggingInterceptor;
    }

    private Interceptor interceptor(Map headMap) {
        Iterator iter = headMap.entrySet().iterator();
        Interceptor interceptor = chain -> {
            Request.Builder builder = chain.request().newBuilder();
            while ((iter.hasNext())) {
                Map.Entry entry = (Map.Entry) iter.next();
                String key = (String) entry.getKey();
                String val = (String) entry.getValue();
                builder.header(key, val);
            }
            return chain.proceed(builder.build());
        };
        return interceptor;
    }

    private X509TrustManager x509TrustManager() {
        return new X509TrustManager() {
            @Override
            public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
            }

            @Override
            public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
            }

            @Override
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return new java.security.cert.X509Certificate[]{};
            }
        };
    }
}
